package missObjects;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

import db.RawData;
import RofMission.RofMissionParams;

/**
 * Class to handle plane
 * @author lefuneste
 *
 */
public class RofMissAirplane extends RofMissionObject {

	private int AIlevel;
	private String script;
	private AirplaneUse airplaneUse;
	private double fuel;
	private int payload;
	
	public int getAIlevel() {
		return AIlevel;
	}
	public void setAIlevel(int aIlevel) {
		AIlevel = aIlevel;
	}
	public AirplaneUse getAirplaneUse() {
		return airplaneUse;
	}
	public void setAirplaneUse(AirplaneUse airplaneUse) {
		this.airplaneUse = airplaneUse;
	}
	public double getFuel() {
		return fuel;
	}
	public void setFuel(double fuel) {
		this.fuel = fuel;
	}
	public int getPayload() {
		return payload;
	}
	public void setPayload(int payload) {
		this.payload = payload;
	}
	
	public String getScript() {
		return script;
	}
	public void setScript(String script) {
		this.script = script;
		
	
	}
	
	/**
	 * Airplane creator
	 * @param index : number of airplane in mission file
	 * @param script : 
	 * @param model : 
	 * @param AIlevel
	 * @param payload
	 * @param fuel
	 * @param airplaneUse : use of the airplane in mission => player, landing, takeoff
	 * @param numberInformation : for squad, airplane number in formation
	 */
	
	public RofMissAirplane(int index, RofMissionParams params, AirplaneUse airplaneUse, int numberInformation) {
		boolean addEgress=false;
		
		this.objectType="Plane";
		this.indexInfile=index;
		this.model=params.getPlaneModel(airplaneUse);
		this.script=params.getPlaneScript(airplaneUse);
		this.AIlevel=params.getAILevel(airplaneUse);
		this.payload=params.getPayload(airplaneUse);
		this.fuel=params.getFuel(airplaneUse);
		this.airplaneUse=airplaneUse;
		
		int startInAir=0;	
		
		switch (airplaneUse) {
			case PLAYER:
				startInAir=0;
				break;
			case LAND:
				startInAir=1;
				break;
			case TAKEOFF:
				startInAir=0;
				break;
		}
		
		//standard raw datas for Plane
		int i=1;
		RawData rawLine=new RawData(i++, "Script = "+this.script+";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Model = "+this.model+";");
		this.unProcessedData.add(rawLine);
		 rawLine=new RawData(i++, "Country = 101;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Desc = \"\";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Skin = \"\";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "AILevel = "+this.AIlevel+";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "CoopStart = 0;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "NumberInFormation = "+numberInformation+";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Vulnerable = 1;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Engageable = 1;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "LimitAmmo = 1;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "StartInAir = "+startInAir+";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Time = 60;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "DamageReport = 50;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "DamageThreshold = 1;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "PayloadId = "+this.payload+";");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "AiRTBDecision = 0;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "DeleteAfterDeath = 1;");
		this.unProcessedData.add(rawLine);
		rawLine=new RawData(i++, "Fuel = "+this.fuel+";");
		this.unProcessedData.add(rawLine);
						
	}
		
	
	/**
	 * Airplane creator for airfield related planes
	 * @param index : number of airplane in mission file
	 * @param script : 
	 * @param model : 
	 * @param AIlevel
	 * @param payload
	 * @param fuel
	 * @param airplaneUse : use of the airplane in mission => player, landing, takeoff
	 * @param airfield : airfield form which taking coord & orientation, not used for player plane.
	 */
	
	public RofMissAirplane(int index, RofMissionParams params, AirplaneUse airplaneUse, RofMissObjAirfield airfield) {
		//generic part of constructor for airfield
		this(index,params,airplaneUse,0);

		//airfield related plane specific part
		if (airfield !=null ) {

			//compute position using Airfield informations
			switch (airplaneUse) {
			case PLAYER:
				this.name="\"Player plane\"";
				//override AILevel to make plane usable by player
				this.AIlevel=0;
				this.Xpos=airfield.getXpos();
				this.Ypos=airfield.Ypos;
				this.Zpos=airfield.getZpos();
				this.Xori=0;
				this.Zori=0;
				this.Yori=airfield.getYori();
				break;
				
			case LAND:
				// Airplane position : params.getLandSpawnDist() km away in airfield landing axis
				double reverse=1;
				double angleCor=0;
				if (params.isAirfieldReversed(airfield)) {
					reverse=-1;
					angleCor=180;
				}
				
				this.Xpos=airfield.getXLP()-reverse*(params.getLandSpawnDist()*Math.cos(Math.toRadians(airfield.getOriLP()))*2);
				this.Ypos=airfield.Ypos+params.getLandSpawnAlt();
				this.Zpos=airfield.getZLP()-reverse*(params.getLandSpawnDist()*Math.sin(Math.toRadians(airfield.getOriLP()))*2);
				this.name="\"Land_"+airfield.name.replace("\"", "")+"_"+airfield.fileID+","+index+"\"";
				this.Xori=0;
				this.Yori=airfield.getOriLP()+angleCor;
				this.Zori=0;
				
				break;
				
			case TAKEOFF:
				// Reverse takeoff position : params.getTakeoffSpawnDist() km away in airfield landing axis
				reverse=-1;
				angleCor=180;
				
				this.Xpos=airfield.getXLP()-reverse*(params.getTakeoffDist()*Math.cos(Math.toRadians(airfield.getOriLP())));
				this.Ypos=airfield.Ypos;
				this.Zpos=airfield.getZLP()-reverse*(params.getTakeoffDist()*Math.sin(Math.toRadians(airfield.getOriLP())));
				
				//if multiple planes put the first one at the left. otherwise it will be at middle.
				if (params.getNumberOfPlaneTakeoff() >= 1) { 
					double takeOffWidth = params.getTakeoffSpacing()*(params.getNumberOfPlaneTakeoff()-1);
					this.Xpos+=-reverse*Math.cos(Math.toRadians(airfield.getOriLP()-90))*(-takeOffWidth/2);
					this.Zpos+=-reverse*Math.sin(Math.toRadians(airfield.getOriLP()-90))*(-takeOffWidth/2);
				}
				
				this.name="\"Takeoff_"+airfield.name.replace("\"", "")+"_"+airfield.fileID+","+index+"\"";
				this.Xori=0;
				this.Yori=airfield.getOriLP()+angleCor;
				this.Zori=0;
				break;
			}
		}
	}
	
	/**
	 * Airplane creator for planes related to a flight
	 * @param index : number of airplane in mission file
	 * @param script : 
	 * @param model : 
	 * @param AIlevel
	 * @param payload
	 * @param fuel
	 * @param airplaneUse : use of the airplane in mission => player, landing, takeoff
	 * @param airfield : airfield form which taking coord & orientation, not used for player plane.
	 */
	
	public RofMissAirplane(int index, RofMissionParams params, AirplaneUse airplaneUse, RofMissAirplane leaderPlane, int numberInFormation) {
		//generic part of constructor
		this(index,params,airplaneUse,numberInFormation);

		//compute position using leading plane informations
		this.Xpos=leaderPlane.Xpos;
		this.Ypos=leaderPlane.Ypos;
		this.Zpos=leaderPlane.Zpos;
		this.name="\""+leaderPlane.name.replace("\"", "")+"_"+numberInFormation+","+"\"";
		this.Xori=0;
		this.Yori=leaderPlane.Yori;
		this.Zori=0;
		
		//add offset for multiple takeoff or landing planes
		switch (airplaneUse) {
		
		case TAKEOFF:
			this.setXpos(leaderPlane.getXpos()-params.getTakeoffSpacing()*numberInFormation*Math.cos(Math.toRadians(leaderPlane.getYori()-90)));
			this.setZpos(leaderPlane.getZpos()-params.getTakeoffSpacing()*numberInFormation*Math.sin(Math.toRadians(leaderPlane.getYori()-90)));
		break;
		
		case LAND:
			this.setXpos( this.getXpos()-params.getLandingSeparation()*numberInFormation*Math.cos(Math.toRadians(this.getYori())));
			this.setZpos(this.getZpos()-params.getLandingSeparation()*numberInFormation*Math.sin(Math.toRadians(this.getYori())));
		break;
		default:
			break;
						
		}
	}	
}
